class Variable extends Term {
    Term value;
    
    public Variable() {
        kind = Kind.VARIABLE;
        
        value = null;
    }
    
    public boolean bound() {
        return value != null;
    }
    
    public void bind(Term value) {
        this.value = value;
    }
    
    public void unbind() {
        value = null;
    }
    
    public Term deref() {
        if(!bound()) {
            return this;
        }
        /*
        while(value.kind == Kind.VARIABLE && ((Variable)value).bound()) {
            value = ((Variable)value).value;
        }
        */
        return value.deref();
    }
    
    public boolean contains(Term t) {
       if(value == null)
            return false;
        else
            return value.contains(t);
    }
    
    public String toString() {
        if(value == null) {
            return "*";
        }
        else {
            return value.toString();
        }
    }
    
    public char coerceToChar() throws ClassCastException {
        Term t = deref();
        if(t.kind == Kind.VARIABLE) throw new ClassCastException("Unbound");
        return t.coerceToChar();
    }
    
    public String coerceToString() throws ClassCastException {
        Term t = deref();
        if(t.kind == Kind.VARIABLE) throw new ClassCastException("Unbound");
        return t.coerceToString();
    }
}
